<?php
define('IN_FANWE', true);
error_reporting(E_ERROR);

class FanweService
{
	public $db = NULL;
	public $session = NULL;
	public $memory = NULL;
	public $is_init = false;
	public $is_memory = true;
	public $is_session = true;
	public $is_admin = false;
	public $is_user = true;
	public $is_cron = true;
	public $is_setting = true;
	public $is_group_city = false;
	public $config = array();
	public $var = array();
	public $cache_list = array(
		'nav',
		'city',
		'goods',
		'link'
	);
	
	public $allow_global = array(
		'GLOBALS' => 1,
		'_GET' => 1,
		'_POST' => 1,
		'_REQUEST' => 1,
		'_COOKIE' => 1,
		'_SERVER' => 1,
		'_ENV' => 1,
		'_FILES' => 1,
	);
	
	
	public function &instance()
	{
		static $_instance = NULL;
		if($_instance === NULL)
			$_instance = new FanweService();
		return $_instance;
	}
	
	public function FanweService()
	{
		if(phpversion() < '5.3.0')
			set_magic_quotes_runtime(0);
		
		define('FANWE_ROOT', str_replace('\\', '/',substr(dirname(__FILE__), 0, -12)));
		if(!file_exists(FANWE_ROOT.'./public/install.lock'))
		{
			header('Location: install.php');
			exit;
		}
		define('MAGIC_QUOTES_GPC', function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc());
		define('ICONV_ENABLE', function_exists('iconv'));
		define('MB_ENABLE', function_exists('mb_convert_encoding'));
		define('EXT_OBGZIP', function_exists('ob_gzhandler'));
		define('TIMESTAMP', time());
		
		if(!@include(FANWE_ROOT.'./core/function/global.func.php'))
		{
			exit('not found global.func.php');
		}
		
		define('IS_ROBOT', checkRobot());
		
		require import("function/time");
		
		if(function_exists('ini_get'))
		{
			$memory_limit = @ini_get('memory_limit');
			if($memory_limit && getBytes($memory_limit) < 33554432 && function_exists('ini_set'))
			{
				ini_set('memory_limit', '128M');
			}
		}
		
		foreach ($GLOBALS as $key => $value)
		{
			if (!isset($this->allow_global[$key]))
			{
				$GLOBALS[$key] = NULL;
				unset($GLOBALS[$key]);
			}
		}
		
		global $_FANWE;
		$_FANWE = array();
		$_FANWE['uid'] = 0;
		$_FANWE['sid'] = '';
		$_FANWE['client_ip'] = getClientIp();
		$_FANWE['config'] = array();
		$_FANWE['setting'] = array();
		$_FANWE['user'] = array();
		$_FANWE['group'] = array();
		$_FANWE['cookie'] = array();
		$_FANWE['cache'] = array();
		$_FANWE['session'] = array();
		$_FANWE['lang'] = array();
		$_FANWE['host'] = getSiteHost();
		$_FANWE['referer'] = '';
		$_FANWE['php_self'] = htmlspecialchars($_SERVER['SCRIPT_NAME'] ? $_SERVER['SCRIPT_NAME'] : $_SERVER['PHP_SELF']);
		$_FANWE['site_url'] = '';
		$_FANWE['site_root'] = '';
		$_FANWE['site_port'] = '';
		
		$site_path = substr($_FANWE['php_self'], 0, strrpos($_FANWE['php_self'], '/'));
		$_FANWE['site_url'] = htmlspecialchars('http://'.$_SERVER['HTTP_HOST'].$site_path);
		
		$url = parse_url($_FANWE['site_url']);
		$site_root = isset($url['path']) ? $url['path'] : '';
		
		if(defined('SUB_DIR'))
		{
			$_FANWE['site_url'] = str_replace(SUB_DIR, '', $_FANWE['site_url']);
			$site_root = str_replace(SUB_DIR, '', $site_root);
		}
		
		define('SITE_PATH',$site_root);
		define('SITE_URL', $_FANWE['site_url']);
		
		$this->var = & $_FANWE;
		
		$this->buildConfig();
		$this->buildInput();
		$this->buildOutput();
	}
	
	public function initialize()
	{
		if(!$this->is_init)
		{
			$this->buildDb();
			$this->buildMemory();
			$this->buildSetting();
			$this->buildCron();
			$this->buildCache();
			$this->buildUser();
			$this->buildSession();
			$this->buildRewriteArgs();
			$this->buildGroupCity();
		}
		
		$this->is_init = true;
		
		define('TPL_PATH', SITE_PATH.'/tpl/'.$this->var['setting']['tpl_dir'].'/');
		define('PUBLIC_PATH', SITE_PATH.'/public/');
		
		@include(FANWE_ROOT.'./tpl/'.$this->var['setting']['tpl_dir'].'/function.php');
		
		$city_name = '';

		if(isset($this->var['current_city']) && $this->var['current_city']['py'] != CHINA_CITY_PY)
			$city_name = $this->var['current_city']['name'];
		
		$this->var['setting']['site_title'] = htmlspecialchars(str_replace('{$city_name}',$city_name,$this->var['setting']['site_title']));
		$this->var['setting']['seo_keyword'] = htmlspecialchars(str_replace('{$city_name}',$city_name,$this->var['setting']['seo_keyword']));
		$this->var['setting']['seo_content'] = htmlspecialchars(str_replace('{$city_name}',$city_name,$this->var['setting']['seo_content']));
		
		if($this->var['setting']['shop_closed'] == 1 && !$this->is_admin)
		{
			showError(lang('common','site_close'),lang('common','site_close_content'),'',0,true);
		}
	}
	
	private function buildConfig()
	{
		$config = array();
		@include FANWE_ROOT.'./public/config.global.php';
		if(empty($config))
		{
			systemError('config_not_found');
		}

		if(empty($config['security']['authkey']))
		{
			$config['security']['authkey'] = md5($config['cookie']['cookie_pre'].$config['db'][1]['dbname']);
		}

		if(empty($config['debug']) || !file_exists(import('function/debug')))
		{
			define('SYS_DEBUG', false);
		}
		elseif($config['debug'] === 1 || $config['debug'] === 2 || !empty($_REQUEST['debug']) && $_REQUEST['debug'] === $config['debug'])
		{
			define('SYS_DEBUG', true);
			if($config['debug'] == 2)
				error_reporting(E_ALL);
		}
		else
		{
			define('SYS_DEBUG', false);
		}
		
		define('CHINA_CITY_PY', $config['china_py']);
		unset($config['china_py']);
		
		timezoneSet($config['timezone']);
		
		define('TIME_UTC', gmtTime());

		$this->config = & $config;
		$this->var['config'] = & $config;

		if(substr($config['cookie']['cookie_path'], 0, 1) != '/')
		{
			$this->var['config']['cookie']['cookie_path'] = '/'.$this->var['config']['cookie']['cookie_path'];
		}
		
		$this->var['config']['cookie']['cookie_pre'] = $this->var['config']['cookie']['cookie_pre'].substr(md5($this->var['config']['cookie']['cookie_path'].'|'.$this->var['config']['cookie']['cookie_domain']), 0, 4).'_';
		$this->var['authkey'] = md5($config['security']['authkey'].$_SERVER['HTTP_USER_AGENT']);
		
		$this->var['form_hash'] = formHash();
		define('FORM_HASH', $this->var['form_hash']);
	}
	
	private function buildInput()
	{
		if (isset($_GET['GLOBALS']) ||isset($_POST['GLOBALS']) ||  isset($_COOKIE['GLOBALS']) || isset($_FILES['GLOBALS']))
		{
			systemError('request_tainting');
		}

		if(!MAGIC_QUOTES_GPC)
		{
			$_GET = fAddslashes($_GET);
			$_POST = fAddslashes($_POST);
			$_COOKIE = fAddslashes($_COOKIE);
			$_FILES = fAddslashes($_FILES);
		}

		$pre_length = strlen($this->config['cookie']['cookie_pre']);
		foreach($_COOKIE as $key => $val)
		{
			if(substr($key, 0, $pre_length) == $this->config['cookie']['cookie_pre'])
			{
				$this->var['cookie'][substr($key, $pre_length)] = $val;
			}
		}

		if($_SERVER['REQUEST_METHOD'] == 'POST' && !empty($_POST))
			$_GET = array_merge($_GET, $_POST);
		
		foreach($_GET as $k => $v)
		{
			$this->var['request'][$k] = $v;
		}
		
		$this->var['mod'] = empty($this->var['request']['mod']) ? '' : htmlspecialchars($this->var['request']['mod']);
		$this->var['isajax'] = empty($this->var['request']['isajax']) ? 0 : 1;
		$this->var['page'] = empty($this->var['request']['page']) ? 1 : max(1, intval($this->var['request']['page']));
		$this->var['sid'] = $this->var['cookie']['sid'] = isset($this->var['cookie']['sid']) ? htmlspecialchars($this->var['cookie']['sid']) : '';
		$this->var['marketing'] = 'marketing_'.$this->var['authkey'].'_'.toDate(TIME_UTC,'Y-m-d');
		fSetCookie('marketing',authcode($this->var['marketing'],'ECODE'),0,1,false,false);
		S('User')->setReferrals();
		if(!empty($this->var['cookie']['ucdata']))
		{
			$this->var['ucdata'] = base64_decode(authcode($this->var['cookie']['ucdata'], 'DECODE'));
			fSetCookie('ucdata','');
		}
	}
	
	private function buildOutput()
	{
		if($this->config['security']['url_xss_defend'] && $_SERVER['REQUEST_METHOD'] == 'GET' && !empty($_SERVER['REQUEST_URI'])) 
		{
			$this->_xssCheck();
		}
		
		if($this->config['security']['attack_evasive'] && (!defined('MODULE_NAME') || !in_array(MODULE_NAME.'/'.ACTION_NAME, array('Misc/verify'))))
		{
			require_once import('include/security');
		}

		$allow_gzip = $this->config['output']['gzip'] && empty($this->var['ajax']) && EXT_OBGZIP;
		setGlobal('gzip_compress', $allow_gzip);
		ob_start($allow_gzip ? 'ob_gzhandler' : NULL);
		setGlobal('charset', $this->config['output']['charset']);
		define('CHARSET', $this->config['output']['charset']);
		@header('Content-Type: text/html; charset='.CHARSET);
	}
	
	private function buildDb()
	{
		require import('class/db');
		require import('class/mysql');
		
		$class = 'DbMySql';
		if(count($this->var['config']['db']['slave']))
		{
			require import('class/mysqlslave');
			$class = 'DbMysqlSlave';
		}
		
		$this->db = &DB::object($class);
		$this->db->setConfig($this->config['db']);
		$this->db->connect();
	}
	
	private function buildMemory()
	{
		require import('class/memory');
		$this->memory = new Memory();
		if($this->is_memory)
		{
			$this->memory->init($this->config['memory']);
		}
		$this->var['memory'] = $this->memory->type;
	}
	
	private function buildSession()
	{
		require import('class/session');
		$this->session = new Session();
		if($this->is_session)
		{
			$this->session->init($this->var['cookie']['sid'], $this->var['client_ip'], $this->var['uid']);
			$this->var['sid'] = $this->session->sid;
			$this->var['session'] = $this->session->var;
			
			if($this->var['sid'] != $this->var['cookie']['sid'])
			{
				fSetCookie('sid', $this->var['sid'], 86400);
			}
			
			if($this->var['uid'] && ($this->session->isnew || ($this->session->get('last_activity') + 600) < TIME_UTC))
			{
				$this->session->set('last_activity', TIME_UTC);
				if($this->session->is_new)
				{
					DB::update('user_status', array('last_ip' => $this->var['client_ip'], 'last_visit' => TIME_UTC), "uid='".$this->var['uid']."'");
				}
			}
		}
	}
	
	private function buildUser()
	{
		if($this->is_user)
		{
			if($auth = getGlobal('auth', 'cookie'))
			{
				$auth = fAddslashes(explode("\t", authcode($auth, 'DECODE')));
			}
			
			list($user_pwd, $user_id) = empty($auth) || count($auth) < 2 ? array('','') : $auth;

			if($user_id)
			{
				$user = S('User')->getUserById($user_id);
			}
			
			if(!empty($user) && $user['user_pwd'] == $user_pwd)
			{
				$this->var['user'] = $user;
			}
			else
			{
				$this->buildGuest();
			}
		}
		else
		{
			$this->buildGuest();
		}
		
		if(empty($this->var['cookie']['last_visit']))
		{
			$this->var['user']['last_visit'] = TIME_UTC - 3600;
			fSetCookie('last_visit', TIME_UTC - 3600, 86400 * 30);
		}
		else
		{
			$this->var['user']['last_visit'] = $this->var['cookie']['last_visit'];
		}
		
		setGlobal('uid', $this->var['user']['id']);
		setGlobal('user_name', addslashes($this->var['user']['user_name']));
		setGlobal('group_id', $this->var['user']['group_id']);
	}
	
	private function buildGuest()
	{
		setGlobal('user', array( 'uid' => 0, 'user_name' => '', 'email' => '', 'group_id' => 3, 'score' => 0));
	}
	
	private function buildCron()
	{
		if($this->is_cron)
		{
			require import("class/cron");
			Cron::run();
		}
	}
	
	private function buildSetting()
	{
		require import("function/cache");
		
		if($this->is_setting)
		{
			loadCache('setting');
		}
		
		if(!is_array($this->var['setting']))
		{
			$this->var['setting'] = array();
		}
	}
	
	private function buildCache()
	{
		require_once import("function/cache");
		!empty($this->cache_list) && loadCache($this->cache_list);
	}
	
	private function buildRewriteArgs()
	{
		if(intval($this->var['setting']['url_route']) > 0)
		{
			switch(MODULE_NAME.'/'.ACTION_NAME)
			{
				case 'now/index':
				case 'now/search':
				case 'now/today':
				case 'now/custom':
					getRewriteArgs(array('cat','city_py','sort','prices','area','keyword','page'));
				break;
				
				case 'goods/index':
				case 'goods/search':
					getRewriteArgs(array('site','cat','date','city_py','sort','prices','area','keyword','page'));
				break;
			}
		}
	}
	
	private function buildGroupCity()
	{
		if($this->is_group_city)
		{
			$citys = $this->var['cache']['city'];
			
			if(!empty($this->var['request']['city_py']) && isset($citys['all'][$this->var['request']['city_py']]))
				$this->var['cookie']['city_py'] = $this->var['request']['city_py'];
			
			if(empty($this->var['cookie']['city_py']))
			{
				if(IS_ROBOT)
				{
					$this->var['cookie']['city_py'] = CHINA_CITY_PY;
				}
				else
				{
					require import('class/iplocation');
					$ip_location = new IpLocation();
					$ip_address = $ip_location->getAddress($this->var['client_ip']);
					$ip_area = $ip_address['area1'];
					
					foreach($citys['all'] as $ip_city)
					{
						if(strpos($ip_city['name'],$ip_area) !== false || strpos($ip_area,$ip_city['name']) !== false)
						{
							$this->var['cookie']['city_py'] = $ip_city['py'];
							break;
						}
					}
				}
			}
			
			if(empty($this->var['cookie']['city_py']))
				$this->var['cookie']['city_py'] = $citys['default'];
			
			define('CURRENT_CITY_PY', $this->var['cookie']['city_py']);
			
			fSetCookie('city_py', $this->var['cookie']['city_py']);

			$this->var['current_city'] = $citys['all'][$this->var['cookie']['city_py']];
			
			unset($citys);
		}
	}
	
	private function _xssCheck()
	{
		$temp = strtoupper(urldecode(urldecode($_SERVER['REQUEST_URI'])));
		if(strpos($temp, '<') !== false || strpos($temp, '"') !== false || strpos($temp, 'CONTENT-TRANSFER-ENCODING') !== false)
		{
			systemError('request_tainting');
		}
		return true;
	}
}
?>